/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <基本类型.h>
#include <几何数据.h>

#include <向量.h>
#include <三角形.h>
#include <vector>
#include <set>
#include <map>

#include "缓存.h"
#include "core/shader_tranform.h"
#include "core/shader_binding_ID.h"
#include "core/shader_curve.h"
#include "core/结构数据.h"
#include "引擎枚举数据.h"


#define DEF_网格自定义属性槽数量 16



struct EngineAPI_EXPORT S_线管创建参数;
struct EngineAPI_EXPORT S_绘图框架;
struct EngineAPI_EXPORT S_光追后端;
struct EngineAPI_EXPORT S_着色;
struct EngineAPI_EXPORT S_管线;
struct EngineAPI_EXPORT S_材质管线;
struct EngineAPI_EXPORT S_GPU计算;
struct EngineAPI_EXPORT S_2D画布;
struct EngineAPI_EXPORT S_UI渲染环境;
struct EngineAPI_EXPORT S_Mesh;
struct EngineAPI_EXPORT S_Scene;
struct EngineAPI_EXPORT S_摄像机;
struct EngineAPI_EXPORT S_物体;
struct EngineAPI_EXPORT S_Window;
struct EngineAPI_EXPORT C_菜单;
struct EngineAPI_EXPORT C_Widget管理;

CORE_ARRAY_HANDLE(S_纹理组, S_纹理*)

using t_管线布局 = S_结构指针;
//using t_着色参数设置 = S_结构指针;
typedef struct __p_Struct *t_着色参数设置;






typedef struct {
	S_板载缓存* m_平面图形GPU缓存_顶点;
	S_板载缓存* m_平面图形GPU缓存_索引;
	S_板载缓存* m_平面图形GPU缓存_序列元素;
	S_板载缓存* m_平面图形GPU缓存_索引元素;
	S_板载缓存* m_平面图形GPU缓存_线索引;
	S_板载缓存* m_平面图形GPU缓存_渐变颜色;
	S_板载缓存* m_平面图形GPU缓存_效果控制;

	S_板载缓存* m_2D面板变换G;
	S_板载缓存* m_2D面板变换L;
	S_板载缓存* m_2D面板颜色;
	S_板载缓存* m_2D凸包图元属性;

	S_板载缓存* m_2DGPU缓存_采样纹理ID;



	S_GPU内存块 m_平面矩形;
	S_GPU内存块 m_平面圆角矩形;
	S_GPU内存块 m_平面左圆角矩形;
	S_GPU内存块 m_平面右圆角矩形;
	S_GPU内存块 m_平面上圆角矩形;
	S_GPU内存块 m_平面下圆角矩形;
	S_GPU内存块 m_平面左上角矩形;
	S_GPU内存块 m_平面左下角矩形;
	S_GPU内存块 m_平面下右上矩形;
	S_GPU内存块 m_平面下右下矩形;
	S_GPU内存块 m_平面圆形;
	S_GPU内存块 m_平面横向直线;
	S_GPU内存块 m_平面纵向直线;



	/*********************** 三维区 **********************/
	S_板载缓存* m_3DGPU缓存_顶点;
	S_板载缓存* m_3DGPU缓存_索引;
	S_板载缓存* m_3DGPU缓存_变换;
	S_板载缓存* m_3DGPU缓存_面颜色;



	/************************ 公用 ************************/



	/************************ 纹理 ************************/
	S_纹理采样器* m_UI模糊采样器;


}S_几何图形缓存;


typedef struct {
	S_结构指针	设备;
	int32		队列族索引;
	S_结构指针	渲染环境;
	S_结构指针*	列队;
}S_逻辑设备;

typedef struct {
	S_结构指针	设备;
	int32		ID;
	S_结构指针	物理设备属性;
}S_物理设备;

struct S_设备 {
	S_物理设备					物理设备;
	std::vector<S_逻辑设备>	逻辑设备;
};


typedef struct {
	
	S_材质管线* m_管线_面[3];
	S_材质管线* m_管线_线[3];
	S_材质管线* m_管线_点[3];
	S_材质管线* m_管线_盒[3];
	S_材质管线* m_管线_注视牌面[3];
	//S_材质管线* m_管线_网格刻度线[3];
	S_材质管线* m_管线_单色光照面[3];
	S_材质管线* m_管线_颜色ID面[3];
	S_材质管线* m_管线_调试面[3];

	S_材质管线* m_管线_网格基面;

	
}S_3D渲染线管集;


typedef struct {
	
	S_材质管线* m_管线_线[3];
	S_材质管线* m_管线_图像[3];
	S_材质管线* m_管线_文字[3];
	S_材质管线* m_管线_多边形[3];
	
	S_材质管线*	m_管线_凸包图元面[3];
	S_材质管线*	m_管线_凸包图元线[3];

	S_材质管线* m_管线_刻度线[3];
	S_材质管线* m_管线_纹理图像[3];

	S_材质管线* m_管线_图像合成;
	S_材质管线* m_管线_UI合成;


	S_GPU计算*	m_计算管线_图像合成;


}S_2D渲染线管集;

#define DEF_渲染环境着色管线          \
        S_2D渲染线管集*	m_2D渲染管线; \
        



typedef struct {
	S_结构指针 m_像机;
	S_结构指针 m_矩阵;
	S_结构指针 m_视口;
	S_结构指针 m_裁剪;
	S_结构指针 m_GPU参数;

	S_结构指针 m_顶点属性;
	S_结构指针 m_片源属性;

}S_2D渲染参数;


typedef struct {
	void*	m_常量推送;
	uint32	m_常量推送字节大小;
	uint32	m_常量推送绑定阶段;
}S_GPU常量;


struct S_内存分配 {
	std::set<uint64>           m_内存分配偏移;
	std::vector<S_GPU偏移大小> m_内存回收偏移;

	uint64	maxNum = 0;
};


typedef struct {
	uint64		m_Type;
	uint64		m_线程数量;
	S_结构指针	m_逻辑设备;
	S_结构指针*	m_命令缓存;
}S_子集绘图命令;


typedef struct {
	void** m_参数槽;
	uint32* m_参数类型;
	uint8* m_绑定位置;
	uint16* m_绑定数量;

	uint16	m_参数数量;

	S_GPU纹理参数槽* m_纹理槽;

	//废弃
	S_结构对象* m_GPU布局描述;
}S_GPU参数槽;

typedef struct {
	uint32 光采样;
	uint32 反弹次数;
	uint32 采样次数;
}S_RayRenderAttr;

typedef struct {
	uvec2	m_瓦片ID;
	uvec2	m_瓦片分辨率;

	uint32	帧采样编号;
	int32	环境材质ID;

	uint32	点光源数量;
}S_Ray渲染配置;

typedef struct {
	S_CurvePoint2*	point;
	uint64			count;
}S_曲线;

typedef struct {
	uvec2* 端点索引;
	uint64	count;
}S_曲线段;

typedef struct EngineAPI_EXPORT {
	S_曲线** 曲线;
	uint32   count;
	int8     name[32];
	void* ObPtr;
}S_曲线通道;

typedef struct EngineAPI_EXPORT {
	S_List* 曲线通道;
	uint32	通道num;
}S_动画曲线组;





/************************************** 纹理 ****************************************/


enum class E_预设颜色 {
	e_黑色,
	e_白色,
};

struct EngineAPI_EXPORT S_纹理采样器创建参数 {
	E_纹理拉伸方式 U;
	E_纹理拉伸方式 V;
	E_纹理拉伸方式 W;

	E_预设颜色	m_预设预设;
};


//就是包含多个纹理对象 S_纹理*
typedef struct {
	S_Array* data;
}S_纹理集;



struct EngineAPI_EXPORT S_纹理添加列队 {
	std::string     m_加载路径;
	struct S_纹理*  m_纹理对象;
	struct S_Scene* m_Scene;
	//void*			m_内存数据;
	uvec3           m_新大小;
	bool			m_加载到内存完成;
};

enum E_纹理分组类型 {
	e_2D纹理,
	e_字符纹理,
	e_渲染输出层,
};




//typedef struct {
//	S_结构指针* 加速结构引用;
//	uint32		引用数量;
//}S_顶层加速结构参数;


/************************************ 光栅渲染 ****************************************/


typedef struct {
	S_GPU内存块		m_灯光属性ID;
	S_纹理集*		m_深度阴影纹理集;
}S_灯光系统;













//=================== 物理可视数据 ======================



typedef struct EngineAPI_EXPORT {
	uint32* index;
	uint32	num;
}S_DomUnitIndex;


typedef struct EngineAPI_EXPORT {
	uvec3	m_分辨率;
	vec3	m_世界大小;
	vec3	m_域世界偏移;
	float32	m_单元大小;
}S_DomProp;
typedef struct EngineAPI_EXPORT {
	uvec4	m_分辨率;
	vec4	m_世界大小;
	vec4	m_域世界偏移;
	//float32	m_单元大小;
}S_域绘制属性;

typedef struct EngineAPI_EXPORT {
	S_DomProp	m_单元属性;
	
	//vec3	m_域世界大小;
	//vec3	m_域单元大小;
	//uvec3	m_分辨率;
	uint8* m_Mask;
}S_域区;


//typedef struct {
//	uint32 m_关联骨骼数量;
//	uint32 m_骨骼内存偏移;
//}S_骨骼属性;


struct EngineAPI_EXPORT S_体素 {
	uvec3					m_维度;
	std::vector<vec3>		m_坐标;
	std::vector<int8>		m_Mask;
	std::vector<uint32>		m_Index;
	std::vector<vec4>		m_法线;
	//std::vector<float32>	m_长度;
};



typedef E_事件是否传递(*fp_Widget快捷键事件)(struct C_Widget* self, E_键位执行状态 状态);
typedef struct {
	E_键位映射类型		m_Type;
	fp_Widget快捷键事件	event;
	struct C_Widget*	发生组件;
	E_键位执行状态		状态;
}S_键位映射;



typedef struct EngineAPI_EXPORT _S_八叉树子空间 {
	_S_八叉树子空间* m_子集[8];
	//S_VecSphere			m_坐标;
	vec3				m_坐标;
	float32				m_域大小;
	uint8				m_层;

	void* m_数据;

}S_八叉树子空间;

typedef struct EngineAPI_EXPORT _S_点距八叉树 {
	S_八叉树子空间* m_空间;
	vec3				m_空间偏移;
	//此空间大小为BOX的宽度 不能是半径
	float32				m_空间大小;
	float32				m_最小单元大小;
	uint8				m_层深度;

	E_值类型			m_映射的数据类型;
	void* m_映射的数据;
}S_点距八叉树;





//============================================= 计算着色器 ==================================================
struct S_后期处理 {
	S_GPU计算* g_物体描边着色器;

	S_GPU计算* g_光栅环境后期;
	S_GPU计算* g_光栅阴影计算;
	S_GPU计算* g_光栅后期合成;
};



/******************************************* 网格 **********************************************/


typedef struct {
	S_材质管线*		m_Material;
	uint32			m_区间槽索引;

	//废弃
	S_GPU参数槽		m_参数槽;
}S_管线槽;

typedef struct {
	uvec3*	m_元素区间;
	uint32	m_多维元素数量;
}S_网格元素;


struct S_2D渐变控制 {
	std::string colorKey;
	vec2	xy1;
	vec2	xy2;
	float32	r;
	bool	径向;
};


struct S_2D图元属性 {
	std::string		效果引用;
	E_图层混合模式	混合模式;

	S_RGBA8UI		填充颜色;
	S_RGBA8UI		描边颜色;

	float32			线宽;

	bool			填充;
	bool			描边;
};

struct S_推送常量 {
	void*	m_常量推送;
	uint32	m_常量推送字节大小;
	uint32	m_常量推送绑定阶段;
};

struct S_网格包 {
	S_Mesh*						m_Mesh;
	std::vector<S_材质管线*>	m_多维材质槽;

	S_推送常量					m_常量推送;
	float32						m_深度偏移;
};




/******************************************* 多边形 **********************************************/


struct S_点 {
	vec3				co;
	std::vector<uint32>	edge;
};

struct S_边 {
	S_结构指针			polygon;
	std::vector<uvec2>	edge;
	int32				渲染模式;
};

struct S_面 {
	S_结构指针			polygon;

	std::vector<uint32>	vertIndex;
	std::vector<uint32> uvIndex;
	std::vector<uint32> edge;
	

	//包含多层UV 所以需要区间标示 x:UV索引数组偏移 y:UV坐标索引数量
	std::vector<uvec2>  uvLoopIndex;

	vec3				面中心;
	vec3				面法线;
	int32				材质槽;
	uint32				ID;
	bool				面平直;

	S_面(S_结构指针 p):polygon(p), 面中心({}), 材质槽(0), ID(0), 面平直(false) {}
};

#include "core/polygon.h"

// 存储多边形数据的结构体
struct PolygonData {
	std::vector<vec2>					point;
	std::vector<std::vector<uint32_t>>	edges;
	std::vector<E_PathType2D>			path_type;
	S_2D图元属性						style;
};

struct S_PolygonEdge {
	uvec2 m_viewindex;
	S_PolygonEdge(uvec2 index) : m_viewindex(index) {

	}
	//bool operator > () {
	//
	//}
};


struct S_多边形 {
	std::vector<vec3>					m_顶点;
	std::vector<std::vector<uint32>>	m_顶点关联边;
	std::vector<std::vector<uint32>>	m_顶点关联面;

	std::vector<vec3>	m_法线;
	std::vector<vec2>	m_UV;
	std::vector<uvec2>	m_边;

	std::vector<S_面*>	m_面;

	std::map<std::string, std::vector<vec2>> m_UV层;


	S_多边形元素Array*  m_元素组;
	
	uint8 m_UV层数量;

	std::map<std::u16string, S_Array*> m_点自定义属性;
	std::map<std::u16string, S_Array*> m_面自定义属性;

	//废弃
	std::vector<S_边*>	m_边_过时成员;
	std::vector<uint32>	m_UV索引;
};



struct EngineAPI_EXPORT S_网格自定义属性 {
	E_值类型		m_Type;
	std::u16string*	m_Name;
	uint32			m_分布方式;
	S_多边形*		m_多边形;
	uint32			m_OffsetID;
	uint32			m_对应材质ID;
};

struct EngineAPI_EXPORT S_实例自定义属性 {
	E_值类型		m_Type;
	std::u16string*	m_Name;
	uint32			m_OffsetID;
};




//==================================== 平面数据 =============================================
typedef struct {
	vec2 point;
	vec2 uv_width;
	uvec2 AA_type;
}S_2D线;

typedef struct {
	vec2 point;
	uvec2 ICO_Size;
	uvec2 AA_type;
}S_2D图标;

typedef struct {
	vec2 point;
	uvec2 CharOffset_Num;
	uvec2 AA_type;
}S_2D字符;

typedef struct {
	vec2 coord;
	vec2 weights;
	vec2 normal;
}S_2D图元顶点;







//============================================= UI ===================================================

typedef bool(*fp_on_菜单项点击)(struct C_Widget* self, const std::u16string, uint16 id);

struct S_菜单项创建参数 {
	std::u16string			name;
	std::u16string			ico;
	std::u16string			快捷键;
	struct S_菜单创建参数* 子菜单参数;
};

struct S_菜单创建参数 {
	fp_on_菜单项点击 mf_菜单项点击;
	std::vector<S_菜单项创建参数> item;
};

struct EngineAPI_EXPORT S_时间线 {
	float32	m_时间线坐标;
	float32 m_时间线缩放;
	//uint32	m_线;
	float64 m_时间;
	float32 m_帧率;

	vec2 m_区间;

	S_时间线() {
		m_时间线坐标 = 0;
		m_时间线缩放 = 10;
		//m_线 = 0;
		m_时间 = 0;
		m_帧率 = 5;

		m_区间 = {0,250};
	}
};

struct EngineAPI_EXPORT S_轨道层 {
	DEF_WString name;
	std::vector<S_TrackSample*> m_层采样条;
};

struct EngineAPI_EXPORT S_轨道 {
	std::vector<S_轨道层*> m_轨道层;
};


typedef struct {
	float32	m_调试占比;
	int32	m_调试层方向;
	int32	m_调试层;
	int32	m_渲染模式;

	uint32	m_渲染层ID;
	uint32	m_渲染元素;

	bool	m_开启后期;
	bool	m_开启调试;

}S_3D视口属性;








/**************************************** 着色线管 ***************************************/


class C_DescriptorSetLayout {
public:
	C_DescriptorSetLayout(){}
	virtual			~C_DescriptorSetLayout(){}
};

class C_DescriptorSet {
public:
	C_DescriptorSet(){}
	
	virtual			~C_DescriptorSet(){}
	virtual void	f_bind(S_推送常量& m_Ctx) = 0;
	//virtual void	f_addDescriptorSet(S_设备环境& ctx, C_DescriptorSetLayout& layout){}
};




struct EngineAPI_EXPORT S_着色器创建参数 {
	uint32			m_绑定位置;
	uint32			m_着色阶段;
	E_板载缓存类型	m_参数类型;
};

struct EngineAPI_EXPORT S_着色顶点输入参数 {
	uint32		m_绑定位置;
	uint32		m_元素大小;
	uint32		m_输入数据类型;
	E_数据格式	m_数据格式;
};

struct EngineAPI_EXPORT S_着色器加载参数 {
	std::string			path;
	std::vector<uint32>	code;
	E_着色阶段			阶段;
};

struct EngineAPI_EXPORT S_常量推送创建参数 {
	uint32 阶段;
	uint32 偏移;
	uint32 字节数;
};

struct EngineAPI_EXPORT S_着色器创建配置 {
	//废弃
	std::vector<S_着色器创建参数>	m_参数布局;

	std::vector<S_着色顶点输入参数>	m_顶点配置;
	std::vector<S_着色器加载参数>	m_Paths;
	std::vector<S_常量推送创建参数>	m_常量偏移和字节数;
};

struct EngineAPI_EXPORT S_着色器管线创建参数 {
	std::vector<S_着色顶点输入参数>		m_顶点配置;
	std::vector<S_着色器加载参数>		m_Paths;
	std::vector<C_DescriptorSetLayout*>	m_参数布局;
	
	std::vector<S_常量推送创建参数>		m_常量偏移和字节数;
};



typedef struct {
	S_管线*			m_Pipeline;
	S_着色*			m_Shader;
	S_结构对象*		m_参数布局;		//S_GPU参数设置描述
	E_几何着色类型	m_几何类型;

	//废弃
	S_结构指针		m_GPU参数set;

}S_着色线管;

typedef struct {
	S_着色线管* m_着色线管;
	S_着色线管* m_阴影着色线管;
	S_着色线管* m_环境着色线管;
	S_着色线管* m_几何着色线管;
	S_着色线管* m_UI渲染线管;
	S_着色线管* m_UI合成线管;
}S_管线组引用;

struct EngineAPI_EXPORT S_线管创建参数 {
	ivec2	m_视口大小;
	vec2	m_视口深度;

	ivec2	m_裁剪偏移;
	ivec2	m_裁剪大小;

	uint32		m_视口数量;
	E_绘制方式	m_绘制方式;
	E_填充模式	m_填充模式;
	E_混合模式	m_透明混合模式;
	E_混合模式	m_颜色混合模式;

	E_混合因子	m_源颜色混合因子;
	E_混合因子	m_目标颜色混合因子;
	E_混合因子	m_源透明通道因子;
	E_混合因子	m_目标透明通道因子;

	E_MS次数	m_采样;

	float32		m_深度偏移;

	bool	m_图元重启;
	//uint8	m_阶段数量;
	bool	m_启用深度测试;
	bool	m_启用写入深度;
	bool	m_启用深度边界;
	bool	m_启用混合;

	E_管线槽 m_槽;

	S_线管创建参数(ivec2 viewSize) {
		m_视口大小 = viewSize;
		m_视口深度 = { 0.0f, 1.0f };
		m_视口数量 = 1;

		m_裁剪偏移 = { 0,0 };
		m_裁剪大小 = viewSize;

		m_采样		= E_MS次数::e_MS_1;
		m_绘制方式	= E_绘制方式::e_三角形;
		m_填充模式	= E_填充模式::e_填充面;


		m_透明混合模式 = E_混合模式::e_相加;
		m_颜色混合模式 = E_混合模式::e_相加;

		m_源颜色混合因子	= E_混合因子::e_源透明通道;
		m_目标颜色混合因子	= E_混合因子::e_一减源透明通道;
		m_源透明通道因子	= E_混合因子::e_源透明通道;
		m_目标透明通道因子	= E_混合因子::e_一减源透明通道;

		m_深度偏移 = 0.0f;
		m_图元重启 = false;
		m_启用深度测试 = true;
		m_启用写入深度 = true;
		m_启用深度边界 = false;
		m_启用混合 = true;

		m_槽 = E_管线槽::e_颜色渲染;
	}
};

typedef void(*fp_set材质GPU参数配置)(struct S_材质管线* mat, void* ob, void* mesh, uint8 元素, uint32 多维子元素);







/****************************************** 渲染面 ************************************************/
#define DEF_VK_窗口交换面           \
    VkSurfaceKHR	m_vk_surface;   \
    VkSwapchainKHR	m_vk_swapchain; \
	VkSemaphore		m_vk_Semaphore; \
    E_MS次数	m_MS;               \
	S_帧缓存*	m_Frame;            \
	ivec2		viewSize;

struct S_WindowSurface {
	S_结构对象* m_vk_surface;
	S_结构对象* m_vk_swapchain;
	E_MS次数 m_MS;
};

typedef enum {
	e_绘制类型_序列,
	e_绘制类型_索引,
	e_绘制类型_无顶点索引,
	e_绘制类型_间接,
	e_绘制类型_间接索引,
	e_绘制类型_结束,
}S_元素绘制类型;


typedef struct {
	DEF_渲染环境着色管线

	S_3D渲染线管集* m_3D渲染管线;

	S_结构指针  m_帧缓存;
	S_结构指针	m_设备;
	S_结构指针	m_物理设备;

}S_渲染环境;

typedef struct {
	E_绘图API		m_Type;
	S_物理设备		m_物理设备;
	S_逻辑设备		m_逻辑设备;

	E_MS次数		m_采样数;
	S_渲染环境*     m_绘图环境;
	S_绘图框架*		m_绘图框架;
	S_几何图形缓存* m_几何图形;

	uint32			m_全局设备ID;
	bool			m_支持光追;

}S_设备环境;



struct S_帧缓存 {
	uvec2		m_Size;
	vec4		m_清除颜色;
	bool		m_多重采样;
	uint32		m_颜色通道数量;
	uint32		m_深度通道数量;

	//窗口交换链纹理
	struct S_纹理* m_颜色图像;
	struct S_纹理* m_深度图像;

	S_帧缓存(const uvec2 size = { 1,1 });

	virtual void	f_渲染到纹理(uint32 texID_color, uint32 texID_depth = 0) {}
	virtual void	f_渲染到纹理结束() {}

	virtual void	f_release(bool 销毁交互纹理 = false) = 0;
	virtual void	f_reSize(uvec2 size) {};
	virtual void	f_构建交换链缓存(S_设备环境& ctx, uint8 附件数量) = 0;
};

CORE_ARRAY_HANDLE(S_帧缓存组, S_帧缓存*)


typedef struct {
	S_设备环境*	m_Ctx;
	S_帧缓存*	m_帧缓存;

	S_纹理*		m_Color[6];
	S_纹理*		m_Depth[6];
	
	uint32		m_纹理数量;

	S_纹理集*			m_平面绑定纹理集;
	S_GPU纹理参数槽		m_合成纹理绑定槽;
	C_DescriptorSet*	m_DS;

	uint32		m_纹理绑定ID;
	uint8		m_叠加类型;
	uint8		m_交换ID;

}S_Surface3D;




typedef struct EngineAPI_EXPORT {
	
} S_光追实例;

struct S_光追环境 {

};

struct EngineAPI_EXPORT S_渲染层 {
	S_设备环境 m_Ctx;

	S_GPU内存块 m_光追顶层加速结构;
	S_GPU内存块 m_光追实例变换;
	S_GPU内存块 m_光追实例物体;
	uint32		m_遮罩模式;

	std::set<struct S_Object*>	m_渲染物体映射;
	void*						m_光追描述集;

};

struct EngineAPI_EXPORT S_渲染世界 {
	S_设备环境 m_Ctx;

	std::vector<S_渲染层*> m_层;
	
	S_GPU内存块 m_物体指针;

	S_纹理集* m_输出纹理;

	S_纹理* m_渲染纹理_最终合成;
	S_纹理* m_渲染纹理_漫反射;
	S_纹理* m_渲染纹理_深度;
	S_纹理* m_渲染纹理_法线;
	S_纹理* m_渲染纹理_自发光;
	S_纹理* m_渲染纹理_光照;

	S_纹理采样器* m_渲染纹理采样器;

	S_GPU纹理参数槽 m_输出纹理槽;
	S_GPU内存块		m_全局绑定参数;

	void* m_光追描述集;

};

struct S_着色文本块 {
	std::u16string			m_一行;
	std::vector<S_RGBA8UI>	m_颜色;
};

struct S_文档文本 {
	//std::u16string			m_Text;
	std::vector<S_着色文本块> m_文本块;

	//std::vector<std::u16string>			m_文本块;
	//std::vector<std::vector<S_RGBA8UI>>	m_Color;
	//bool								m_子块折叠;
};

struct S_字体字符属性 {
	int16  width;
	int16  height;

	float32 horiBearingX;
	float32 horiBearingY;
	int16  horiAdvance;

	float32  vertBearingX;
	float32  vertBearingY;
	int16  vertAdvance; 
};

struct S_矢量字体 {
	std::vector<uvec2>				m_矢量文字索引区间;
	std::vector<uvec2>				m_矢量文字边索引区间;
	std::vector<S_字体字符属性>		m_字符属性;
	S_GPU内存块						m_矢量文字顶点;
	S_GPU内存块						m_矢量文字索引;
	S_GPU内存块						m_矢量文字轮廓索引;
};





struct EngineAPI_EXPORT S_纹理采样器 {
	//uvec3	m_拉伸方式;
	S_设备环境 m_Ctx;

	virtual ~S_纹理采样器() {}
};

struct S_TextueSetsProp {
	S_纹理集*	m_纹理集;
	uint		m_激活ID;
	uint		m_DrawMode;
};






/***************************************** 物体渲染 *********************************************/


class C_场景渲染环境 {
	C_DescriptorSet*	m_DS_颜色;

public:
	C_场景渲染环境(S_设备环境& ctx);
	~C_场景渲染环境();

	C_DescriptorSet* m_管线参数设置_None;
	C_DescriptorSet* m_管线参数设置_F_L3_ImageSampleArray;
	C_DescriptorSet* m_管线参数设置_VS_Proj;
	C_DescriptorSet* m_管线参数设置_VS_Mat4;


	//E_管线槽 m_槽;
	//void f_添加管线(S_材质管线* 管线, E_管线槽 槽);

};




//============================================= 物理 ==================================================

typedef struct {
	S_GPU内存块	m_Loc;
	S_GPU内存块	m_Vel;
	S_GPU内存块	m_Rot;
	S_结构指针	m_外力;
	S_GPU内存块	m_Size;
	S_结构指针	m_出生;
	//S_结构指针	m_寿命;
	S_GPU内存块	m_寿命;
	S_GPU内存块	m_年龄;

	S_结构指针	m_粒子状态;
	ivec2			m_发射区间;
	uint32			m_Count;
	uint32			m_发射粒子ID偏移;

	S_结构指针	m_物理引擎;
	S_物理体* m_物理属性;
	E_粒子绘制类型	m_绘制类型;
	S_设备环境		m_Ctx;

	//S_材质* m_Material;
	//S_GPU参数布局	m_GPU参数布局;
	vec2 m_大小区间;
	float32 m_初始粒子大小;
	float32 m_初始寿命;
	float32 m_寿命随机比;

	uint32 m_包含属性;


	class S_Mesh** m_渲染物体网格;
	uint32 m_渲染物体数量;
	uint32 m_随机种子;

	bool m_随机大小;

}S_粒子系统配置;


typedef struct _S_施加物理力 {
	vec3 pos;
	vec3 vec;
	vec3 force;
	int32 bodyID;
	float32 dis;
}S_施加物理力;






#define _S_ElementSelect       \
typedef struct {		       \
	S_UI32Array*   Index;      \
	void*          Element;	   \
	E_值类型       Type;	   \
}S_ElementSelect;

_S_ElementSelect;


CORE_ARRAY_HANDLE(S_ElementSelectArray, S_ElementSelect*)







struct EngineAPI_EXPORT S_材质管线 {
	S_设备环境* m_Ctx;

	S_着色线管* m_着色线管;
	S_着色线管* m_阴影着色线管;
	S_着色线管* m_环境着色线管;
	S_着色线管* m_几何着色线管;
	S_着色线管* m_UI渲染线管;
	S_着色线管* m_UI合成线管;

	uint32		m_材质属性ID;
	S_GPU内存块	m_材质属性;


	bool		m_深度遮挡;
	bool		m_引用着色线管;
	bool		m_独立统一缓存;

	//S_结构指针	m_并行计算GPU参数set;

	fp_set材质GPU参数配置	mf_GPU参数配置;

	//std::vector<t_着色参数设置> m_自定义参数;
	std::vector<C_DescriptorSetLayout*>	m_着色参数布局;

	std::vector<S_网格自定义属性>	m_网格自定义属性布局;
	std::vector<S_GPU内存块>		m_自定义属性;
	//一开始就分配了16个位置
	S_GPU内存块						m_材质自定义属性索引;

	S_GPU纹理参数槽 m_纹理槽;

	//废弃
	//fp_set材质GPU参数布局	mf_GPU材质槽更新 = nullptr;


	S_材质管线(S_设备环境* ctx = nullptr) : m_Ctx(ctx) {
		m_独立统一缓存 = false;

		m_材质属性 = {};
		m_引用着色线管 = false;
		m_深度遮挡 = true;

		m_着色线管 = nullptr;
		m_阴影着色线管 = nullptr;
		m_环境着色线管 = nullptr;
		m_几何着色线管 = nullptr;
		m_UI渲染线管 = nullptr;
		m_UI合成线管 = nullptr;

		mf_GPU参数配置 = nullptr;
		//mf_GPU材质槽更新 = nullptr;

		m_材质属性ID = 0;

		m_纹理槽 = {};

		//assert(S_材质::g_属性索引);
		
	}
	virtual ~S_材质管线(){};

	virtual S_材质管线* f_copy() { return nullptr; }


	
};
//typedef S_材质 t_GPU数据;

Inline void f_pl_引用管线(S_材质管线* material, const S_管线组引用& 管线组) {
	material->m_着色线管 = 管线组.m_着色线管;
	material->m_阴影着色线管 = 管线组.m_阴影着色线管;
	material->m_环境着色线管 = 管线组.m_环境着色线管;
	material->m_几何着色线管 = 管线组.m_几何着色线管;
	material->m_UI渲染线管 = 管线组.m_UI渲染线管;
	material->m_UI合成线管 = 管线组.m_UI合成线管;
}










typedef struct {
	S_Viewport*		m_视口;
	S_Rect2D*		m_裁剪;
	

	float32			m_线宽;
	uint32          m_顶点内存偏移;
	uint32          m_顶点数量;
	uint32          m_索引内存数量;
	uint32          m_索引内存偏移;
	uint32			m_实例数量;
	uint32			m_实例偏移;
	uint32			m_间接偏移;
	uint32			m_间接数量;

	uint32			m_槽;
	E_管线槽		m_线管槽;

	//废弃
	S_GPU内存块*	m_间接;
	S_板载缓存*		m_视图投影矩阵;

}S_渲染参数;







//============================================= 场景 ===================================================

typedef bool(*fp_场景更新)(struct S_Scene* scene);

typedef struct {
	S_Scene*	m_Scene;
	fp_场景更新	mf_更新前;
	fp_场景更新	mf_更新后;
}S_场景回调;


typedef void(*fn_3D视口渲染回调)(S_摄像机* camera, S_3D视口属性& 层属性, uint64 视口标识符);
typedef uvec2(*fn_3D视口调整分辨率)(uvec2 分辨率);
typedef struct {
	fn_3D视口渲染回调	mf_渲染;
	fn_3D视口渲染回调	mf_轮廓渲染;
	fn_3D视口渲染回调	mf_阴影环境渲染;
	fn_3D视口渲染回调	mf_渲染后期合成;

	uint64				m_视口标识符;

	fn_3D视口调整分辨率	mf_设置分辨率;

	C_场景渲染环境*		m_场景渲染环境;
}S_渲染回调;



typedef struct EngineAPI_EXPORT {
	float32 相交宽度;
	float32 相交点到起点距离;
	int32	点索引;
}S_点拾取;

typedef struct EngineAPI_EXPORT {
	vec3	交点;
	float32 相交宽度;
	float32 相交点到起点距离;
	int32	线索引;
	int32	线元素;
}S_线拾取;

typedef struct EngineAPI_EXPORT {
	S_物体* 物体;
	uint32	实例ID;
	float32	相交深度;
	float32	平面距离;
	uint32  元素索引;
	uint8	拾取模式;
}S_物体拾取信息;

typedef struct EngineAPI_EXPORT {
	vec3    交点;
	float32 相交宽度;
	int32	面索引;
}S_面拾取;

typedef struct EngineAPI_EXPORT {
	S_物体* 物体;
	float32 相交宽度;
	float32 相交点到起点距离;
	uint32	点索引;
}S_点拾取信息;

typedef void(*fun_渲染前更新p)(S_结构指针 scene);






//---------------------------------------- 废弃 -------------------------------------------

//typedef void(*fp_set材质GPU参数布局)(struct S_材质* mat, S_GPU参数布局& layout, uint16 网格属性缓存槽数量);		//废弃

typedef struct EngineAPI_EXPORT {
	S_板载缓存** m_参数槽;
	uint8* m_绑定位置;

	S_纹理** m_纹理槽;
	uint8* m_纹理绑定位置;

	uint16			m_绑定数量;
	uint16			m_纹理数量;

}S_GPU参数布局;

typedef struct EngineAPI_EXPORT {
	S_材质管线*		g_材质;

	void**		m_参数槽;
	S_纹理**	m_纹理信息;
	uint8*		m_绑定位置;
	uint32*		m_参数类型;

	uint16			m_参数元素数量;
	uint16			m_纹理参数数量;
	//S_TexArrayRes* m_纹理库对象;	
	//S_结构对象指针	m_GPU参数set;

	const void* m_常量属性;

}S_2D笔刷;

typedef struct EngineAPI_EXPORT {
	S_2D笔刷* 字体笔刷;
	//和 S_单色文本绘制ID id_文本 是同一个
	uint16		文本ID;
	uint16		区间大小;
}S_2D文本对象;

typedef struct EngineAPI_EXPORT {
	S_板载缓存* 属性;
	S_GPU内存块* 变换;
	S_GPU内存块* 颜色;
	S_GPU内存块* 线属性;
	S_GPU内存块* 纹理属性;

	suvec2		m_属性ID;

	uint32		层;
	bool		链接属性;
	bool		链接变换;
	bool		链接颜色;
	bool		链接线属性;

	bool		链接纹理属性;

}S_凸边图元;

typedef struct EngineAPI_EXPORT {
	S_板载缓存*		属性;
	bool			链接属性;
	S_GPU内存块*	变换;
	bool			链接变换;
	S_GPU内存块*	颜色;
	bool			链接颜色;
	S_GPU内存块*	渐变;
	bool			链接渐变;
	uint32			层;
}S_渐变图元;



void f_logs_writeFile(const std::string& info);


#define DEF_记录日志( info ) f_logs_writeFile( info )















